//
// Created by HP on 2025/11/26.
//

#include "Train.h"
#include <iostream>

// 火车类型常量定义
const std::string TrainType::HighSpeed = "highSpeed";
const std::string TrainType::BulletTrain = "bulletTrain";
const std::string TrainType::OrdinaryTrain = "ordinaryTrain";

Train::Train() : Model("trains") {
    this->type = TrainType::OrdinaryTrain; // 默认设为普通火车
    setTableDefault("name", "VARCHAR(50) NOT NULL UNIQUE");
    setTableDefault("type", "VARCHAR(50) NOT NULL");
    setTableDefault("company", "VARCHAR(100) NOT NULL");
    setTableDefault("createdAt", "DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP");
}

void Train::bind(const std::string& key, const std::string& value) {
    if (!TableCols.count(key)) {
        std::cerr << "Error: Invalid key for train bind" << std::endl;
        return;
    }
    
    std::string selectSql = "SELECT * FROM " + TableName + " WHERE " + key + " = '" + Model::escapeSqlLiteral(value) + "';";
    std::vector<std::map<std::string, std::string>> result = DBConnector::getInstance()->query(selectSql);

    if (result.empty()) {
        std::cerr << "bind failed: SQL execution error or no result. SQL: " << selectSql << std::endl;
        return;
    }

    std::cout << "bind success. Table: " << TableName << std::endl;

    if (result.size() > 1) {
        std::cerr << "Error: Multiple trains found with the same " << key << std::endl;
        return;
    } else if (result.size() == 1) {
        this->id = result[0]["id"];
        this->name = result[0]["name"];
        this->type = result[0]["type"];
        this->company = result[0]["company"];
        this->createdAt = result[0]["createdAt"];
        this->isBind = true;
    }
}

bool Train::save() {
    std::string insertSql = "INSERT INTO " + TableName + " (name, type, company) VALUES ('" 
                          + Model::escapeSqlLiteral(name) + "', '" 
                          + Model::escapeSqlLiteral(type) + "', '" 
                          + Model::escapeSqlLiteral(company) + "');";
    
    int executeCode = DBConnector::getInstance()->execute(insertSql);
    if (executeCode == -1) {
        std::cerr << "save train failed: SQL execution error. SQL: " << insertSql << std::endl;
        std::cerr << "Database error: " << DBConnector::getInstance()->getError() << std::endl;
        return false;
    } else {
        std::cout << "save train success. Table: " << TableName << std::endl;
        return true;
    }
}

int Train::getIdFromKey(const std::string &key, const std::string &value) {
    std::string querySql = "SELECT id FROM trains WHERE " + key + " = '" + Model::escapeSqlLiteral(value) + "';";
    auto result = DBConnector::getInstance()->query(querySql);

    if (result.empty()) {
        return 0;
    }

    int res;
    try {
        res = std::stoi(result[0]["id"]);
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 0;
    }

    return res;
}


